<?php 
class Ebcms {

	public static function db($config=[]){
		static $dbs;
		$config = $config?:\mylib\Config::get('database');
		$key = md5(json_encode($config));
		if (!isset($dbs[$key])) {
			$dbs[$key] = new \Medoo\Medoo($config);
		}
		return $dbs[$key];
	}

	public static function root(){
		$root = pathinfo($_SERVER['SCRIPT_NAME'], PATHINFO_DIRNAME);
		return ($root == DIRECTORY_SEPARATOR) ? '' : $root;
	}
	
	public static function isGet(){
		return isset($_SERVER['REQUEST_METHOD']) && !strcasecmp($_SERVER['REQUEST_METHOD'],'GET');
	}
	
	public static function isPost(){
		return isset($_SERVER['REQUEST_METHOD']) && !strcasecmp($_SERVER['REQUEST_METHOD'],'POST');
	}
	
	public static function isAjax(){
		return ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')) ? true : false;
	}

	public static function isMobile(){
		if (isset($_SERVER['HTTP_VIA']) && stristr($_SERVER['HTTP_VIA'], "wap")) {
		    return true;
		} elseif (isset($_SERVER['HTTP_ACCEPT']) && strpos(strtoupper($_SERVER['HTTP_ACCEPT']), "VND.WAP.WML")) {
		    return true;
		} elseif (isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE'])) {
		    return true;
		} elseif (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/(blackberry|configuration\/cldc|hp |hp-|htc |htc_|htc-|iemobile|kindle|midp|mmp|motorola|mobile|nokia|opera mini|opera |Googlebot-Mobile|YahooSeeker\/M1A1-R2D2|android|iphone|ipod|mobi|palm|palmos|pocket|portalmmm|ppc;|smartphone|sonyericsson|sqh|spv|symbian|treo|up.browser|up.link|vodafone|windows ce|xda |xda_)/i', $_SERVER['HTTP_USER_AGENT'])) {
		    return true;
		} else {
		    return false;
		}
	}

	public static function real_url($file){
		return strpos($file, '://') ? $file : self::root() . $file;
	}

	public static function deldir($dir){
	    if (is_dir($dir)) {
	        $dh = opendir($dir);
	        while ($file = readdir($dh)) {
	            if ($file != "." && $file != "..") {
	                $fullpath = $dir . "/" . $file;
	                if (!is_dir($fullpath)) {
	                    unlink($fullpath);
	                } else {
	                    self::deldir($fullpath);
	                }
	            }
	        }
	        return true;
	    }
	    return false;
	}

	public static function config($name, $default=null){
		if (!$configs = \mylib\Cache::get('configs')) {
			$configs = [];
			$tmp = self::db() -> select('config','*');
			foreach ($tmp as $key => $value) {
				$configs[$value['name']] = $value['value'];
			}
			\mylib\Cache::set('configs', $configs, 3600);
		}
		return isset($configs[$name])?$configs[$name]:$default;
	}

	public static function block($name='', $default=''){
		$key = 'block_' . md5($name);
		if (!$res = \mylib\Cache::get($key)) {
			if (!$block = self::db() -> get('block','*', ['name'=>$name])) {
				return $default;
			}
			switch ($block['type']) {
				case 'text':
					$res = $block['value'];
					break;
				case 'upload':
					$res = self::root() . $block['value'];
					break;
				case 'tpl':
					$res = self::renderTpl(htmlspecialchars_decode($block['value']));
					break;
				case 'editor':
					$res = self::safeHtml(htmlspecialchars_decode($block['value']));
					break;
				
				default:
					$res = $block['value'];
					break;
			}
			if ($block['expire']) {
				\mylib\Cache::set($key, $res, $block['expire']);
			}
		}
		return $res;
	}

	public static function renderTpl($tpl, $data=[]){
		$view = new \mylib\View(\mylib\Config::get('view'));
		return $view -> render($tpl, $data);
	}

	public static function page($total=0, $page=1, $pagenum=20){

		if (!$total) {
			return [];
		}

		$total_page = ceil($total/$pagenum);
		$min = max($page - 3, 1);
		$max = min($page + 3, $total_page?:1);

		$res = [];

		if ($page > 1) {
			$res[] = [
				'text'=>'«',
				'page'=>1,
			];
		}else{
			$res[] = [
				'text'=>'«',
				'disable'=>1,
			];
		}

		if ($max >= $min) {
			for ($i = $min; $i <= $max; $i++) { 
				if ($page == $i) {
					$res[] = [
						'text'=>$i,
						'current'=>1
					];
				}else{
					$res[] = [
						'text'=>$i,
						'page'=>$i,
					];
				}
			}
		}

		if ($page < $total_page) {
			$res[] = [
				'text'=>'»',
				'page'=>$total_page,
			];
		}else{
			$res[] = [
				'text'=>'»',
				'disable'=>1,
			];
		}

		return $res;
	}

	public static function safeHtml($html){
		$elements = [
			'html'      =>  [],
			'body'      =>  [],
			'a'         =>  ['target', 'href', 'title', 'class', 'style'],
			'abbr'      =>  ['title', 'class', 'style'],
			'address'   =>  ['class', 'style'],
			'area'      =>  ['shape', 'coords', 'href', 'alt'],
			'article'   =>  [],
			'aside'     =>  [],
			'audio'     =>  ['autoplay', 'controls', 'loop', 'preload', 'src', 'class', 'style'],
			'b'         =>  ['class', 'style'],
			'bdi'       =>  ['dir'],
			'bdo'       =>  ['dir'],
			'big'       =>  [],
			'blockquote'=>  ['cite', 'class', 'style'],
			'br'        =>  [],
			'caption'   =>  ['class', 'style'],
			'center'    =>  [],
			'cite'      =>  [],
			'code'      =>  ['class', 'style'],
			'col'       =>  ['align', 'valign', 'span', 'width', 'class', 'style'],
			'colgroup'  =>  ['align', 'valign', 'span', 'width', 'class', 'style'],
			'dd'        =>  ['class', 'style'],
			'del'       =>  ['datetime'],
			'details'   =>  ['open'],
			'div'       =>  ['class', 'style'],
			'dl'        =>  ['class', 'style'],
			'dt'        =>  ['class', 'style'],
			'em'        =>  ['class', 'style'],
			'font'      =>  ['color', 'size', 'face'],
			'footer'    =>  [],
			'h1'        =>  ['class', 'style'],
			'h2'        =>  ['class', 'style'],
			'h3'        =>  ['class', 'style'],
			'h4'        =>  ['class', 'style'],
			'h5'        =>  ['class', 'style'],
			'h6'        =>  ['class', 'style'],
			'header'    =>  [],
			'hr'        =>  [],
			'i'         =>  ['class', 'style'],
			'img'       =>  ['src', 'alt', 'title', 'width', 'height', 'id', 'class'],
			'ins'       =>  ['datetime'],
			'li'        =>  ['class', 'style'],
			'mark'      =>  [],
			'nav'       =>  [],
			'ol'        =>  ['class', 'style'],
			'p'         =>  ['class', 'style'],
			'pre'       =>  ['class', 'style'],
			's'         =>  [],
			'section'   =>  [],
			'small'     =>  [],
			'span'      =>  ['class', 'style'],
			'sub'       =>  ['class', 'style'],
			'sup'       =>  ['class', 'style'],
			'strong'    =>  ['class', 'style'],
			'table'     =>  ['width', 'border', 'align', 'valign', 'class', 'style'],
			'tbody'     =>  ['align', 'valign', 'class', 'style'],
			'td'        =>  ['width', 'rowspan', 'colspan', 'align', 'valign', 'class', 'style'],
			'tfoot'     =>  ['align', 'valign', 'class', 'style'],
			'th'        =>  ['width', 'rowspan', 'colspan', 'align', 'valign', 'class', 'style'],
			'thead'     =>  ['align', 'valign', 'class', 'style'],
			'tr'        =>  ['rowspan', 'align', 'valign', 'class', 'style'],
			'tt'        =>  [],
			'u'         =>  [],
			'ul'        =>  ['class', 'style'],
			'video'     =>  ['autoplay', 'controls', 'loop', 'preload', 'src', 'height', 'width', 'class', 'style'],
			'embed'     =>  ['src', 'height','align', 'width', 'class', 'style','type','pluginspage','wmode','play','loop','menu','allowscriptaccess','allowfullscreen'],
			'source'    =>  ['src', 'type']
		];
		$html = strip_tags($html,'<'.implode('><', array_keys($elements)).'>');
		$xml = new \DOMDocument();
		libxml_use_internal_errors(true);
		if (!strlen($html)){
			return '';
		}
		if ($xml->loadHTML('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . $html)){
			foreach ($xml->getElementsByTagName("*") as $element){
				if (!isset($elements[$element->tagName])){
					$element->parentNode->removeChild($element);
				}else{
					for ($k = $element->attributes->length - 1; $k >= 0; --$k) {
						if (!in_array($element->attributes->item($k) -> nodeName, $elements[$element->tagName])){
							$element->removeAttributeNode($element->attributes->item($k));
						}elseif (in_array($element->attributes->item($k) -> nodeName, ['href','src','style','background','size'])) {
							$_keywords = ['javascript:','javascript.:','vbscript:','vbscript.:',':expression'];
							$find = false;
							foreach ($_keywords as $a => $b) {
								if (false !== strpos(strtolower($element->attributes->item($k)->nodeValue),$b)) {
									$find = true;
								}
							}
							if ($find) {
								$element->removeAttributeNode($element->attributes->item($k));
							}
						}
					}
				}
			}
		}
		$html = substr($xml->saveHTML($xml->documentElement), 12, -14);
		$html = strip_tags($html,'<'.implode('><', array_keys($elements)).'>');
		return $html;
	}
}